﻿(function ($) {
    var methods = {
        init: function (options) {
            return this.each(function () {
                var settings = {
            };
            var $this = $(this),
                        data = $this.data('stopWatch'),
                        stopWatch = $('<div />', {
                    });

            // If the plugin hasn't been initialized yet
            if (!data) {
                if (options) {
                    $.extend(settings, options);
                }
                $(this).data('stopWatch', {
                    target: $this,
                    stopWatch: stopWatch,
                    settings: settings,
                    startDate: null,
                    runtime: null
                });
            };
            if (typeof settings.onDisplay === 'function') {
                $(this).bind('display.stopWatch', settings.onDisplay);
            }
        });
    },

    destroy: function () {
        return this.each(function () {
            var $this = $(this), data = $this.data('stopWatch');

            $(window).unbind('.stopWatch');
            data.stopWatch.remove();
            $this.removeData('stopWatch');
        })
    },

    start: function () {
        return this.each(function () {
            var $this = $(this), data = $this.data('stopWatch');
            if (data.startDate != null) { return false; }
            data.startDate = new Date();
            data.runtime = null;
        });
    },

    stop: function () {
        return this.each(function (args) {
            var $this = $(this), data = $this.data('stopWatch');
            if (data.startDate == null) { return false; }
            data.runtime = new Date() - data.startDate;
            if (typeof data.settings.onDisplay === 'function') {
                var params = new Array();
                params = $.map(args, function (value, index) { return value; });
                params.splice(0, 0, data.runtime);
                $(this).triggerHandler('display', params);
            }
            else {
                $this.html(data.runtime);
            }
            data.startDate = null;
        }, arguments);
    },

    displayStats: function () {
        return this.each(function (args) {
            var $this = $(this), data = $this.data('stopWatch');
            if (data.startDate == null) { return false; }
            var time = data.runtime;
            if (data.runtime == null) { time = new Date() - data.startDate; }
            if (typeof data.settings.onDisplay === 'function') {
                var params = new Array();
                params = $.map(args, function (value, index) { return value; });
                params.splice(0, 0, time);
                $(this).triggerHandler('display', params);
            }
            else {
                $this.html(time);
            }
        }, arguments);
    }
};


$.fn.stopWatch = function (method) {
    if (methods[method]) {
        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
    } else if (typeof method === 'object' || !method) {
        return methods.init.apply(this, arguments);
    } else {
        $.error('Method ' + method + ' does not exist on jQuery.stopWatch');
    }
};

$.fn.startTimer = function () {
    $(this).stopWatch('start');
};

$.fn.stopTimer = function () {
    $(this).stopWatch('stop', arguments);
};

$.fn.displayStats = function () {
    $(this).stopWatch('displayStats', arguments);
};

})(jQuery);
